package com.df.ez_game.server.logic.status_sync.controllers.entity;

/**
 * 玩家数据类 - 存储玩家的位置、移动状态等信息
 */
public class PlayerData {
    private long id;              // 玩家ID
    private float x = 0;          // X坐标
    private float y = 0;          // Y坐标
    private float dx = 0;         // X方向速度分量
    private float dy = 0;         // Y方向速度分量
    private boolean isMoving = false; // 是否在移动
    private long lastMoveTimestamp = 0; // 最后移动时间戳
    private long lastClientFrame = 0;   // 最后客户端帧号
    private float speed = 200;    // 移动速度，像素/秒
    
    // 用于位置变化检测的阈值
    private float lastBroadcastX = 0;
    private float lastBroadcastY = 0;
    private float positionThreshold = 5; // 位置变化阈值
    
    // 网络延迟相关
    private long averageLatency = 0;
    private int latencySamples = 0;
    
    // Getters and Setters
    public long getId() {
        return id;
    }
    
    public void setId(long id) {
        this.id = id;
    }
    
    public float getX() {
        return x;
    }
    
    public void setX(float x) {
        this.x = x;
        this.lastBroadcastX = x; // 初始化广播位置
    }
    
    public float getY() {
        return y;
    }
    
    public void setY(float y) {
        this.y = y;
        this.lastBroadcastY = y; // 初始化广播位置
    }
    
    public float getDX() {
        return dx;
    }
    
    public void setDX(float dx) {
        this.dx = dx;
    }
    
    public float getDY() {
        return dy;
    }
    
    public void setDY(float dy) {
        this.dy = dy;
    }
    
    public boolean isMoving() {
        return isMoving;
    }
    
    public void setMoving(boolean moving) {
        isMoving = moving;
    }
    
    public long getLastMoveTimestamp() {
        return lastMoveTimestamp;
    }
    
    public void setLastMoveTimestamp(long lastMoveTimestamp) {
        this.lastMoveTimestamp = lastMoveTimestamp;
    }
    
    public long getLastClientFrame() {
        return lastClientFrame;
    }
    
    public void setLastClientFrame(long lastClientFrame) {
        this.lastClientFrame = lastClientFrame;
    }
    
    public float getSpeed() {
        return speed;
    }
    
    public void setSpeed(float speed) {
        this.speed = speed;
    }
    
    public long getAverageLatency() {
        return averageLatency;
    }
    
    // 更新平均延迟
    public void updateAverageLatency(long newLatency) {
        // 使用滑动平均算法更新延迟
        if (latencySamples < 10) {
            // 前10个样本直接累加平均
            averageLatency = (averageLatency * latencySamples + newLatency) / (latencySamples + 1);
            latencySamples++;
        } else {
            // 之后使用指数加权平均
            averageLatency = (averageLatency * 9 + newLatency) / 10;
        }
    }
    
    // 更新玩家位置
    public void updatePosition(long deltaTime) {
        if (!isMoving) return;
        
        // 将deltaTime从毫秒转换为秒
        float dt = deltaTime / 1000.0f;
        
        // 计算移动距离
        float moveX = dx * speed * dt;
        float moveY = dy * speed * dt;
        
        // 更新位置
        x += moveX;
        y += moveY;
    }
    
    // 检查是否需要广播位置更新（位置变化超过阈值）
    public boolean needBroadcast() {
        float distanceX = Math.abs(x - lastBroadcastX);
        float distanceY = Math.abs(y - lastBroadcastY);
        
        // 当位置变化超过阈值，或者移动状态变化时，需要广播
        if (distanceX >= positionThreshold || distanceY >= positionThreshold || 
            (isMoving && (dx != 0 || dy != 0))) {
            return true;
        }
        
        return false;
    }
    
    // 重置广播标志
    public void resetBroadcastFlag() {
        lastBroadcastX = x;
        lastBroadcastY = y;
    }
    
    // 获取玩家状态的快照
    public PlayerState getState() {
        PlayerState state = new PlayerState();
        state.setId(id);
        state.setX(x);
        state.setY(y);
        state.setDX(dx);
        state.setDY(dy);
        state.setMoving(isMoving);
        state.setTimestamp(System.currentTimeMillis());
        return state;
    }
    
    // 归一化方向向量
    public void normalizeDirection() {
        float length = (float) Math.sqrt(dx * dx + dy * dy);
        if (length > 0) {
            dx = dx / length;
            dy = dy / length;
        }
    }
    
    // 停止移动
    public void stop() {
        isMoving = false;
        dx = 0;
        dy = 0;
    }
    
    @Override
    public String toString() {
        return "PlayerData{" +
                "id=" + id +
                ", x=" + x +
                ", y=" + y +
                ", dx=" + dx +
                ", dy=" + dy +
                ", isMoving=" + isMoving +
                "}";
    }
}
